const {ccclass, property} = cc._decorator;
import Global = require("./GlobalEvents");
import StateMachine = require('./lib/StateMachine');

//平台移动速度
const Plat_SPEED:number = 1400;
//stick生长速度
const Stick_SPEED:number = 600;
//player速度
const Player_SPEED:number = 900;

var FSM = StateMachine.factory({
    init: 'init',
    data: function(game:PlayEvents){
        return {
            game:game
        }
    },
    transitions: [
      { name: 'slidePlat',     from: 'init',  to: 'LerpPlat' },
      { name: 'showNewPlat',     from: 'LerpPlat',  to: 'LerpNewPlat' },
      { name: 'readTouch',     from: 'LerpNewPlat',  to: 'ReadTouch' },
      { name: 'placeStick',     from: 'ReadTouch',  to: 'RotateStick' },
      { name: 'walkStick',     from: 'RotateStick',  to: 'PlayerWalking' },
      { name: 'walkFinish',     from: 'PlayerWalking',  to: 'PlayerWalkEnd' },
      { name: 'walkGood',     from: 'PlayerWalkEnd',  to: 'WalkSuccess' },
      { name: 'walkBad',     from: 'PlayerWalkEnd',  to: 'WalkFault' },  
      { name: 'resetGame',     from: ['init','WalkSuccess','WalkFault'],  to: 'init' },    
    ],
    methods: {
      onSlidePlat:function(){
        this.game.player.node.getComponent(cc.Animation).play('idle');
        //cc.log("onSlidePlat");
        this.game.SlidePlat();
      },
      onShowNewPlat:function(){
        this.game.player.node.getComponent(cc.Animation).play('idle');
        this.game.ShowNewPlat();
      },
      onReadTouch:function(){
        this.game.player.node.getComponent(cc.Animation).play('idle');
        this.game.ReadTouch();
      },
      onPlaceStick:function(){
        this.game.player.node.getComponent(cc.Animation).play('idle');
        this.game.PlaceStick();
      },
      onWalkStick:function(){
        this.game.player.node.getComponent(cc.Animation).play('walk');
        this.game.WalkStick();
      },
      onWalkFinish:function(){
        //this.game.player.node.getComponent(cc.Animation).play('idle');
        this.game.WalkFinish();
      },
      onWalkGood:function(){         
        this.game.player.node.getComponent(cc.Animation).play('idle');
        //this.game.player.node.getComponent(cc.Animation).stop();
        this.game.WalkGood();
      },
      onWalkBad:function(){        
        this.game.player.node.getComponent(cc.Animation).play('fall');
        this.game.WalkBad();
      }       
    }
  });

@ccclass
export default class PlayEvents extends cc.Component {
    
    @property(cc.Node)
    scoreNode: cc.Node = null;

    @property(cc.Label)
    scoreLbl: cc.Label = null;

    @property(cc.Sprite)
    player: cc.Sprite = null;

    @property(cc.Sprite)
    plat0: cc.Sprite = null;

    @property(cc.Sprite)
    plat1: cc.Sprite = null;

    @property(cc.Sprite)
    stick: cc.Sprite = null;

    @property(cc.Sprite)
    coll: cc.Sprite = null;

    @property(cc.Sprite)
    wonderWords: cc.Sprite = null;

    @property(cc.Sprite)
    tutionWords: cc.Sprite = null;

    @property(cc.Sprite)
    endWords: cc.Sprite = null;

    @property({
        type: cc.AudioClip
    })
    stickaudio = null;

    @property({
        type: cc.AudioClip
    })
    wondelfulaudio = null;    

    @property({
        type: cc.AudioClip
    })
    gameoveraudio = null;

    fsm:any = null;
    private playerAnim: cc.Animation = null;
    private scene:cc.Scene = null;    
    
    // LIFE-CYCLE CALLBACKS:
    btnClick(event, customEventData){
        this.node.runAction(cc.fadeOut(2.0));
    };


    onLoad () {        
        this.fsm =new FSM(this);
        let self = this;
        let playerAnim = self.player.node.getComponent(cc.Animation);          
        let scene = cc.director.getScene();
        self.stick.node.zIndex = 9;

        self.tutionWords.node.active = false;
        self.wonderWords.enabled = false;        
        self.endWords.enabled = false;

        let bgrand = Math.ceil(Math.random() * 6) - 1;        
        Global.BGpic = bgrand;        
        let platformpic = Global.Platformpics[bgrand];

        //加载平台图片
        cc.loader.loadRes("bgAtlas", cc.SpriteAtlas, function (err, bgAtlas) {                
            let frame = bgAtlas.getSpriteFrame(platformpic);
            self.plat0.spriteFrame = frame;
            self.plat1.spriteFrame = frame;
        }); 
        //加载天空特效：星星、雪花、云朵
        if(bgrand==1)
        {
            // 加载 Prefab            
            cc.loader.loadRes("Prefab/particle_star", function (err, prefab) {  
                let starNode = cc.instantiate(prefab); 
                starNode.setPosition(540, 1600);
                starNode.parent = scene;
                //starNode.setLocalZOrder(1);
            });  
            //cc.log("par_star");          
        }
        else if(bgrand==3)
        {
            // 加载 Prefab
            cc.loader.loadRes("Prefab/particle_snow", function (err, prefab) {  
                let snowNode = cc.instantiate(prefab);   
                snowNode.setPosition(540, 1880);       
                snowNode.parent = scene;       
                //snowNode.setLocalZOrder(1);         
            });
            //cc.log("par_snow");
        }
        else if(bgrand==0)
        {
        }
        else if(bgrand==5)
        {
            //云朵动画
            this.schedule(this.update5Clouds, 2);
        }
        else
        {
            //云朵动画
            this.schedule(this.update24Clouds, 2);
        }
        this.node.on(cc.Node.EventType.TOUCH_START, function (event) {
            //cc.log(self.tutionWords.enabled); 
            if(self.tutionWords.node.active){                
                self.tutionWords.node.active = false;            
            } 
            if(self.fsm.can('readTouch')){
                self.fsm.readTouch();   
            }

        });
        this.node.on(cc.Node.EventType.TOUCH_END, function (event) {
            //cc.log('TOUCH_END');
            if(self.fsm.can('placeStick')){
                self.fsm.placeStick();   
            }
        });
        
        //self.scoreNode.setLocalZOrder(9);
        self.scoreNode.zIndex = 9;
        cc.director.preloadScene("GameOver", function () {
            cc.log("Next scene preloaded");
        });
           
        this.resetGame();
        //cc.log(this.fsm.state);
        //cc.log(this.fsm.can('slidePlat'));
        if(this.fsm.can('slidePlat')){
            this.fsm.slidePlat();
        }     
        
        //开启右上角的分享
        window["wx"].showShareMenu();        
        //监听右上角的分享调用
        cc.loader.loadRes("Icon_128",function(err,data){            
            window["wx"].onShareAppMessage(function(res){                
                return {                    
                    title: "猴哥有难，快来帮忙！",				
                    imageUrl: data.url,				
                    success(res){                        
                        console.log("转发成功!!!")},                        
                    fail(res){
                        console.log("转发失败!!!")}
                }		
            })	
        }); 

    }

    start ()
    {        
            
    }
    
    resetGame() 
    {        
        Global.GameState = "Init";
        Global.Score = 0;
        Global.NewPlatX = 0;
        Global.WalkDist = 0;
        this.scoreLbl.string = Global.Score.toString();
        //显示教学文字
        if (Global.showTutorial == true) 
        {
            //cc.log(this.tutionWords.enabled);
            this.tutionWords.node.active = true;
            //Global.showTutorial = false;
        }
        else {
        }
        if(Global.GameState=="Init")
        {
            this.fsm.resetGame();        
        }        
    }
    //移动当前平台
    SlidePlat (){   
             
        this.player.node.runAction(
            cc.moveTo(0.5,cc.v2(120,this.player.node.y))
        );   
        if(this.plat0.node.x>0){
            this.plat0.node.runAction(
                cc.moveTo(0.5,cc.v2(-120,this.plat0.node.y))
            );
        }            
        if(this.plat1.node.x>0){
            this.plat1.node.runAction(
                cc.moveTo(0.5,cc.v2(120,this.plat1.node.y))
            );
        }        
        this.stick.node.height = 0;        
        this.stick.node.rotation = 0;
        Global.GameState = "LerpPlat";
        this.stick.node.runAction(
            cc.sequence(                
                cc.moveTo(0.5,cc.v2(120,this.stick.node.y)),
                cc.callFunc(()=>{
                    this.fsm.showNewPlat();
                })
            )
        );
        // cc.log(this.fsm.can('init'));
        // cc.log(this.fsm.state);    
    }
    //展示新平台
    ShowNewPlat (){
        this.plat0.node.width = this.plat1.node.width; 
        this.plat0.node.x = this.plat1.node.x;
        this.plat1.node.x = cc.winSize.width + 120;        
        this.plat1.node.width = 64 + Math.random()*180;        
        Global.NewPlatX = (this.plat0.node.x + this.plat0.node.width) + 100 + Math.random()*(cc.winSize.width*0.5 - 40); 
        if(this.plat1.node.x>cc.winSize.width){
            this.plat1.node.runAction(
                cc.moveTo(0.5,cc.v2(Global.NewPlatX,this.plat1.node.y))
            );
        } 
        Global.GameState = "LerpNewPlat";
        //cc.log(this.plat1.node.width); 
        //cc.log(Global.NewPlatX); 
        //cc.log(Global.GameState);
    }
    //触摸事件
    ReadTouch (){        
        Global.GameState = "ReadTouch";               
        //cc.log(Global.GameState);
    }
    //放平stick
    PlaceStick (){
        //cc.log(this.stick.node.height);
        Global.GameState = "RotateStick";
        if(this.stick.node.height>0)
        {
            Global.WalkDist = this.stick.node.height + this.stick.node.x - this.player.node.x;
        }
        if(Global.isSound==0){
        }
        else{
          cc.audioEngine.play(this.stickaudio, false, 1);
        }
        this.stick.node.runAction(
            cc.sequence(
                cc.delayTime(.1),
                cc.rotateTo(.3,90),                
                cc.callFunc(()=>{
                    this.player.node.width = Global.PlayerWalkW;                            
                    this.player.node.height = Global.PlayerWalkH; 
                    this.fsm.walkStick();
                })
            )
        );
        
    }
    //行走
    WalkStick (){
        Global.GameState = "PlayerWalking";        
        //完美的棍子长度(播放音乐，+1分)
        let stickcond1 = (this.coll.node.x-this.coll.node.width*0.5) - this.stick.node.x
        let stickcond2 = (this.coll.node.x+this.coll.node.width*0.5) - this.stick.node.x
        if((this.stick.node.height>=stickcond1) && (this.stick.node.height<=stickcond2))
        {
            Global.Score += 1;
            this.scoreLbl.string = Global.Score.toString();            
            if(Global.isSound==0){
            }
            else{
                cc.audioEngine.play(this.wondelfulaudio, false, 1);
            }
            //显示wonderful文字延迟1秒后消失                       
            this.wonderWords.node.runAction(              
                cc.sequence(                                        
                    cc.show(),                                      
                    cc.delayTime(.7),                               
                    cc.hide(),                                      
                    )                                
                )                        
        }    
                    
        //cc.log(Global.GameState);
    }
    //行走结束
    WalkFinish (){
        let movecond1 = this.plat1.node.x - (this.plat1.node.width*0.5) - this.stick.node.x - 3;
        let movecond2 = this.plat1.node.x + (this.plat1.node.width*0.5) - this.stick.node.x + 3;             
        if(this.stick.node.height<movecond1)
        {            
            this.stick.node.runAction(
                cc.sequence(
                    cc.delayTime(.1),
                    cc.rotateTo(.3,180),                
                    cc.callFunc(()=>{    
                        this.player.node.width = Global.PlayerFallW;                        
                        this.player.node.height = Global.PlayerFallH;     
                        this.fsm.walkBad();
                    })
                )
            );
        }
        else if(this.stick.node.height>movecond2)
        {            
            this.player.node.runAction(
                cc.sequence(
                    cc.delayTime(.1),                                    
                    cc.callFunc(()=>{           
                        this.player.node.width = Global.PlayerFallW;                        
                        this.player.node.height = Global.PlayerFallH;              
                        this.fsm.walkBad();
                    })
                )
            );            
        }
        else
        {            
            this.player.node.runAction(
                cc.sequence(
                    cc.delayTime(.1),                                    
                    cc.callFunc(()=>{                 
                        this.player.node.width = Global.PlayerW;                        
                        this.player.node.height = Global.PlayerH;        
                        this.fsm.walkGood();
                    })
                )
            );             
        }
        
    }
    //走上新平台
    WalkGood (){
        Global.GameState = "WalkSuccess";
        Global.Score += 1;
        this.scoreLbl.string = Global.Score.toString();
        this.player.node.runAction(
            cc.sequence(
                cc.delayTime(.1),                                    
                cc.callFunc(()=>{
                    this.fsm.resetGame();
                })
            )
        );        
        //cc.log(Global.GameState);        
        let callbak = function () {
            if(this.fsm.can('slidePlat')){
                this.fsm.slidePlat();
            } 
        };
        this.scheduleOnce(callbak, 0.1);
    }
    //跌落平台
    WalkBad (){
        Global.GameState = "WalkFault";             
        if(Global.isSound==0){
        }
        else{    
            let callbak = function () {
                cc.audioEngine.playEffect(this.gameoveraudio, false);
            };
            this.scheduleOnce(callbak, 0.4);
        }   
        //cc.log(Global.GameState);    
          
    }
    //游戏结束
    gameOver ()
    {                 
        if (Global.Score > Global.BestScore) {
            //Global.BestScore = Global.Score;
            //非微信平台存储数据
            cc.sys.localStorage.setItem("BestScore", Global.Score);
            //cc.log(Global.BestScore);
        }                
         //显示gameover文字延迟1秒后消失            
         this.endWords.node.runAction(                
            cc.sequence(                    
                cc.show(),                    
                cc.delayTime(2),                    
                cc.hide(),                       
            )            
        )         
        //游戏结束，淡入淡出
        this.node.runAction(
            cc.sequence(
                cc.delayTime(.5), 
                cc.fadeOut(1),              
                cc.callFunc(()=>{
                    cc.director.loadScene("GameOver");
                })
            )
        );
        
    }

    newClouds (bk: number)
    {
        let scene = cc.director.getScene();
        let cloudrand = 0;
        let bgcloudurl = "";

        if(bk==5)
        {            
            cloudrand = Math.ceil(Math.random() * 6) - 1;
            bgcloudurl =  Global.BG5clouds[cloudrand];
            //cc.log(bgcloudurl);
        }
        else
        {
            cloudrand = Math.ceil(Math.random() * 5) - 1;
            bgcloudurl =  Global.BG24clouds[cloudrand];
        }

        let dynode = new cc.Node("cloudsprite "+ cc.director.getScene().childrenCount);
        let dycloud = dynode.addComponent(cc.Sprite);
        cc.loader.loadRes("bgAtlas", cc.SpriteAtlas, function (err, bgAtlas) {                
            let frame = bgAtlas.getSpriteFrame(bgcloudurl);     
            dycloud.spriteFrame = frame;              
        });            

        let randx = cc.winSize.width + 220;             
        let randy =cc.winSize.height * (1 - Math.random() / 3);
        let randpos = cc.v2(randx, randy);
        let endpos = cc.v2(-220, randy);
        dynode.setPosition(randpos);
        dynode.parent = scene;
        dynode.zIndex = 1;
        //dynode.setLocalZOrder(1);
        //this.scoreNode.setLocalZOrder(9);
        this.scoreNode.zIndex = 9;
        let movplan = cc.moveTo(7, endpos);
        let movend = cc.callFunc(dynode.removeFromParent, dynode);
        let cloudAct = cc.sequence(movplan, movend);
        dynode.runAction(movplan);

    }

    update5Clouds (dt)
    {
        let tmpCloud = this.newClouds(5);
    }

    update24Clouds (dt)
    {
        let tmpCloud = this.newClouds(2);
    }
        
    update (dt) 
    {
        switch(this.fsm.state)
        {
            case 'init':{

                break;
            }
            case 'LerpPlat':{
                                
                break;
            }
            case 'LerpNewPlat':{

                break;
            }
            case 'ReadTouch':{
                this.stick.node.x = this.plat0.node.x + this.plat0.node.width*0.5 - 2;                
                //超过屏幕高度视为最大长度，避免无限制加长
                let heightlimit = cc.winSize.height - this.stick.node.y;                    
                if(this.stick.node.height<=heightlimit)                                
                {                    
                    this.stick.node.height += Stick_SPEED*dt;
                }                
                else                
                {
                    this.stick.node.height = heightlimit;
                }                
                break;
            }
            case 'RotateStick':{

                break;
            }
            case 'PlayerWalking':{      
                if(Global.WalkDist>0)
                {
                    this.player.node.x = this.player.node.x + Player_SPEED*dt;
                    Global.WalkDist -= Player_SPEED*dt;                    
                }
                else if(this.player.node.x>(Global.PlayerWalkW*0.5+cc.winSize.width))
                {
                    this.player.node.x = Global.PlayerWalkW*0.5 + cc.winSize.width;
                    Global.GameState = "PlayerWalkEnd";              
                    //cc.log("out scene!");
                    this.fsm.walkFinish();
                }
                else
                {
                    this.player.node.x = this.player.node.x + Global.WalkDist;
                    Global.GameState = "PlayerWalkEnd";                    
                    this.fsm.walkFinish();
                }
                break;
            }
            case 'PlayerWalkEnd':{
                
                break;
            }
            case 'WalkSuccess':{
                
                break;
            }
            case 'WalkFault':{                
                if(this.player.node.y>(0-this.player.node.height))
                {
                    this.player.node.y -= Player_SPEED*dt;
                }
                else
                {
                    this.player.node.y = this.player.node.y;                    
                    Global.GameState = "GameOver";
                    this.gameOver();
                }                
                break;
            }
        }
        
    }
}
